#include "Plataforma.h"

Plataforma::Plataforma(int x, int y, string rutaImagen, int ancho, int alto, int maximoX, int maximoY, int angulo) : Obstaculo(x, y, rutaImagen, ancho, alto, maximoX, maximoY, angulo) {

	tipo = OBSTACULO;
}

void Plataforma::ColisionarConPersonaje(ObjetoEstatico* personaje, int colX, int colY, int colXvieja, int colYvieja) {

	Personaje* per = dynamic_cast<Personaje*> (personaje);

	if (per->getEstadoParticular() == EstadoPersonaje::SubiendoEscalera) {
		per->setPosicion(per->getPosicionAnt().getX(), per->getPosicionAnt().getY());
		return;
	}

	if (getAngulo() != 0) {
                //cout << "ColisionarConPersonaje angulo: " << getAngulo() << endl;
		if (ColisionOblicua(personaje)) per->StartSonido (SonidosPersonaje::ColisionObstaculo);
		return;
	}

	per->StartSonido (SonidosPersonaje::ColisionObstaculo);

	int ZONA_COLISION_X = per->getAncho() * 0.1;
	int ZONA_COLISION_Y = per->getAlto() * 0.1;

	if (colXvieja != 0) {
		if (per->getVelocidadY() <= 0) {
			per->setVelocidadY(0);
			if (per->getEstado() == EstadoBasico::Saltando) per->setEstado(EstadoBasico::Quieto);
			per->setPosicion(per->getX(), getY() - per->getAlto());
		}
		else {
			per->setVelocidadY(per->getVelocidadY() * (-1));
			per->setPosicion(per->getX(), getY() + getAlto() - ZONA_COLISION_Y);
		}
	}
	else if (colYvieja !=0) {
		if (per->getVelocidadX() < 0) per->setPosicion(getX() + getAncho() - ZONA_COLISION_X, per->getY());
		else per->setPosicion(getX() - per->getAncho() + ZONA_COLISION_X, per->getY());
	}
	else {
		if (colX >= colY) {
			if (per->getVelocidadY() < 0) {
				per->setVelocidadY(0);
				if (per->getEstado() == EstadoBasico::Saltando) per->setEstado(EstadoBasico::Quieto);
				per->setPosicion(per->getX(), getY() - per->getAlto());
			}
			else {
				per->setVelocidadY(per->getVelocidadY() * (-1));
				per->setPosicion(per->getX(), getY() + getAlto() - ZONA_COLISION_Y);
			}
		}
		else {
			if (per->getVelocidadX() < 0) per->setPosicion(getX() + getAncho() - ZONA_COLISION_X, per->getY());
			else per->setPosicion(getX() - per->getAncho() + ZONA_COLISION_X, per->getY());
		}
	}
}

void Plataforma::ColisionarConEnemigo(ObjetoEstatico* movible, int colX, int colY, int colXvieja, int colYvieja) {

	ObjetoMovible* mov = dynamic_cast<ObjetoMovible*> (movible);

	if (getAngulo() != 0) {
                //cout << "ColisionarConEnemigo angulo: " << getAngulo() << endl;
		ColisionOblicua(movible);
		return;
	}

	int ZONA_COLISION_Y = mov->getAlto() * 0.1;

	if (colXvieja != 0) {
		if (mov->getVelocidadY() <= 0) {
			mov->setVelocidadY(0);
			mov->setPosicion(mov->getX(), getY() - mov->getAlto());
			if (mov->getEstado() == EstadoBasico::Saltando) mov->setEstado(EstadoBasico::Quieto);
		}
		else {
			mov->setVelocidadY(mov->getVelocidadY() * (-1));
			mov->setPosicion(mov->getX(), getY() + getAlto() - ZONA_COLISION_Y);
		}
	}
	else if (colYvieja !=0 ) mov->CambiarSentido(getX(), getAncho());

	else {
		if (colX >= colY) {
			if (mov->getVelocidadY() < 0) {
				mov->setVelocidadY(0);
				mov->setPosicion(mov->getX(), getY() - mov->getAlto());
				if (mov->getEstado() == EstadoBasico::Saltando) mov->setEstado(EstadoBasico::Quieto);
			}
			else {
				mov->setVelocidadY(mov->getVelocidadY() * (-1));
				mov->setPosicion(mov->getX(), getY() + getAlto() - ZONA_COLISION_Y);
			}
		}
		else mov->CambiarSentido(getX(), getAncho());
	}
}

int Plataforma::DetectarInclusionLaterales(double x, double y) {

	double aux1,aux2;	
	double m, b;
	aux1 = (vertices.posSupIzq.getY() - vertices.posInfIzq.getY());
	aux2 = (vertices.posSupIzq.getX() - vertices.posInfIzq.getX());
	m = aux1/ aux2; 
	//cout<<"m"<<m<<endl;
	b = vertices.posSupIzq.getY() - m * vertices.posSupIzq.getX();
	double xIzq = (y-b)/m;
	
	aux1=(vertices.posSupDer.getY() - vertices.posInfDer.getY());
	aux2 = (vertices.posSupDer.getX() - vertices.posInfDer.getX());	
	m = aux1  / aux2;
	b = vertices.posSupDer.getY() - m * vertices.posSupDer.getX();
	double xDer=(y-b)/m;

	
	aux1 = (vertices.posSupIzq.getY() - vertices.posSupDer.getY());
	aux2= (vertices.posSupIzq.getX()-vertices.posSupDer.getX());
	m=aux1/aux2;

	//m=(vertices.posSupIzq.getY() - vertices.posSupDer.getY())/(vertices.posSupIzq.getX()-vertices.posSupDer.getX());
	b= vertices.posSupIzq.getY() - m * vertices.posSupIzq.getX();
	int ySup= m*x+b;

        //cout<<"mizq="<<m<<"  b="<<b<<"  y"<<y<<"  xres= "<<xIzq<<endl;

	aux1=(vertices.posInfIzq.getY() - vertices.posInfDer.getY());
	aux2=(vertices.posInfIzq.getX() - vertices.posInfDer.getX());
	m=aux1/aux2;
	//m = (vertices.posInfIzq.getY() - vertices.posInfDer.getY()) / (vertices.posInfIzq.getX()-vertices.posInfDer.getX());
	b = vertices.posInfIzq.getY() - m * vertices.posInfIzq.getX();
	int yInf = m*x +b;
        //cout<<"mder="<<m<<"  b="<<b<<"  y"<<y<<"  xres= "<<xDer<<endl;
//	cout<<"ySup = "<<ySup<<"  yInf = "<<yInf<< "  xIzq = "<<xIzq<<"  xDer = "<<xDer<<endl;
//	cout<<"x = "<<x<<"y = "<<y<<endl;

//      cout << "DetectarInclusion: ";
//      cout << ((x > xIzq && x < xDer) && (y < ySup && y > yInf));
//      cout << " x: " << x;
//      cout << " xIzq: " << xIzq;
//      cout << " xDer: " << xDer;
//      cout << " entre: " << (x > xIzq && x < xDer);
//      cout << " y: " << y;
//      cout << " yInf: " << yInf;
//      cout << " ySup: " << ySup;
//      cout << " entre: " << (y < ySup && y > yInf);
//      cout << endl;
	if(y > ySup && y < yInf){
		if(x < xIzq) return -1;
		if(x> xDer) return 1;
		return 0;	
	
	}
        return 0;

/*  	if(getAngulo()>90){
  		if((x < xIzq && x > xDer) && (y < ySup && y > yInf)) return true;
  	}
*/
	//else return false;
        return 0;
}

bool Plataforma::DetectarInclusion(double x, double y) {

	double aux1,aux2;	
	double m, b;
	aux1 = (vertices.posSupIzq.getY() - vertices.posInfIzq.getY());
	aux2 = (vertices.posSupIzq.getX() - vertices.posInfIzq.getX());
	m = aux1/ aux2; 
	//cout<<"m"<<m<<endl;
	b = vertices.posSupIzq.getY() - m * vertices.posSupIzq.getX();
	double xIzq = (y-b)/m;
	
	aux1=(vertices.posSupDer.getY() - vertices.posInfDer.getY());
	aux2 = (vertices.posSupDer.getX() - vertices.posInfDer.getX());	
	m = aux1  / aux2;
	b = vertices.posSupDer.getY() - m * vertices.posSupDer.getX();
	double xDer=(y-b)/m;

	
	aux1 = (vertices.posSupIzq.getY() - vertices.posSupDer.getY());
	aux2= (vertices.posSupIzq.getX()-vertices.posSupDer.getX());
	m=aux1/aux2;

	//m=(vertices.posSupIzq.getY() - vertices.posSupDer.getY())/(vertices.posSupIzq.getX()-vertices.posSupDer.getX());
	b= vertices.posSupIzq.getY() - m * vertices.posSupIzq.getX();
	int ySup= m*x+b;

        //cout<<"mizq="<<m<<"  b="<<b<<"  y"<<y<<"  xres= "<<xIzq<<endl;

	aux1=(vertices.posInfIzq.getY() - vertices.posInfDer.getY());
	aux2=(vertices.posInfIzq.getX() - vertices.posInfDer.getX());
	m=aux1/aux2;
	//m = (vertices.posInfIzq.getY() - vertices.posInfDer.getY()) / (vertices.posInfIzq.getX()-vertices.posInfDer.getX());
	b = vertices.posInfIzq.getY() - m * vertices.posInfIzq.getX();
	int yInf = m*x +b;
        //cout<<"mder="<<m<<"  b="<<b<<"  y"<<y<<"  xres= "<<xDer<<endl;
//	cout<<"ySup = "<<ySup<<"  yInf = "<<yInf<< "  xIzq = "<<xIzq<<"  xDer = "<<xDer<<endl;
//	cout<<"x = "<<x<<"y = "<<y<<endl;

//      cout << "DetectarInclusion: ";
//      cout << ((x > xIzq && x < xDer) && (y < ySup && y > yInf));
//      cout << " x: " << x;
//      cout << " xIzq: " << xIzq;
//      cout << " xDer: " << xDer;
//      cout << " entre: " << (x > xIzq && x < xDer);
//      cout << " y: " << y;
//      cout << " yInf: " << yInf;
//      cout << " ySup: " << ySup;
//      cout << " entre: " << (y < ySup && y > yInf);
//      cout << endl;

	if ((x > xIzq && x < xDer) && (y > ySup && y < yInf)) return true;
/*  	if(getAngulo()>90){
  		if((x < xIzq && x > xDer) && (y < ySup && y > yInf)) return true;
  	}
*/
	else return false;
}

/*

bool Plataforma::DetectarInclusion(int x, int y) {

	double m, b;
	m = (vertices.posSupIzq.getY() - vertices.posInfIzq.getY())/ (vertices.posSupIzq.getX() - vertices.posInfIzq.getX());
	b = vertices.posSupIzq.getY() - m * vertices.posSupIzq.getX();
	int ySup = m*x + b;
	
	m = (vertices.posSupDer.getY() - vertices.posInfDer.getY())/ (vertices.posSupDer.getX() - vertices.posInfDer.getX());
	b = vertices.posSupDer.getY() - m * vertices.posSupDer.getX();
	int yInf = m*x + b;
	
	double aux1,aux2;
	aux1 = (vertices.posSupIzq.getY() - vertices.posSupDer.getY());
	aux2= (vertices.posSupIzq.getX()-vertices.posSupDer.getX());
	m=aux1/aux2;

	//m=(vertices.posSupIzq.getY() - vertices.posSupDer.getY())/(vertices.posSupIzq.getX()-vertices.posSupDer.getX());
	b= vertices.posSupIzq.getY() - m * vertices.posSupIzq.getX();
	int xIzq = (y - b)/m;
	
cout<<"mizq="<<m<<"  b="<<b<<"  y"<<y<<"  xres= "<<xIzq<<endl;
	aux1=(vertices.posInfIzq.getY() - vertices.posInfDer.getY());
	aux2=(vertices.posInfIzq.getX() - vertices.posInfDer.getX());
	m=aux1/aux2;
	//m = (vertices.posInfIzq.getY() - vertices.posInfDer.getY()) / (vertices.posInfIzq.getX()-vertices.posInfDer.getX());
	b = vertices.posInfIzq.getY() - m * vertices.posInfIzq.getX();
	int xDer = (y - b)/m;
cout<<"mder="<<m<<"  b="<<b<<"  y"<<y<<"  xres= "<<xDer<<endl;
//	cout<<"ySup = "<<ySup<<"  yInf = "<<yInf<< "  xIzq = "<<xIzq<<"  xDer = "<<xDer<<endl;
//	cout<<"x = "<<x<<"y = "<<y<<endl;
	
        cout << "DetectarInclusion: ";
	cout << ((x > xIzq && x < xDer) && (y < ySup && y > yInf));
        cout << " x: " << x;
        cout << " xIzq: " << xIzq;
        cout << " xDer: " << xDer;
        cout << " entre: " << (x > xIzq && x < xDer);
        cout << " y: " << y;
        cout << " yInf: " << yInf;
        cout << " ySup: " << ySup;
        cout << " entre: " << (y < ySup && y > yInf);
        cout << endl;

	if ((x > xIzq && x < xDer) && (y < ySup && y > yInf)) return true;
//  	if(getAngulo()>90){
//  		if((x < xIzq && x > xDer) && (y < ySup && y > yInf)) return true;
//  	}

	else return false;
}


*/

bool Plataforma::DetectarDobleInclusion(ObjetoMovible* personaje, int x, int y) {

    /*
        cout << "DetectarDobleInclusion: ";
	cout << ((x > personaje->getX() && x < (personaje->getX() + personaje->getAncho())) && (y > personaje->getY() && y < (personaje->getY() + personaje->getAlto())));
        cout << " x: " << x;
        cout << " pxIzq: " << personaje->getX();
        cout << " pxDer: " << (personaje->getX() + personaje->getAncho());
        cout << " entre: " << (x > personaje->getX() && x < (personaje->getX() + personaje->getAncho()));
        cout << " y: " << y;
        cout << " pyInf: " << personaje->getY();
        cout << " pySup: " << (personaje->getY() + personaje->getAlto());
        cout << " entre: " << (y > personaje->getY() && y < (personaje->getY() + personaje->getAlto()));
        cout << endl;
  */

	if ((x > personaje->getX() && x < (personaje->getX() + personaje->getAncho())) && (y > personaje->getY() && y < (personaje->getY() + personaje->getAlto()))) {
		return true;
	}
	return false;
}

bool Plataforma::ColisionOblicua(ObjetoEstatico* personaje) {

	ObjetoMovible* per = dynamic_cast<ObjetoMovible*> (personaje);

	int MARGEN_X = per->getAncho()* 0.1;
	int MARGEN_Y = per->getAlto() * 0.1;

	Punto infDer (personaje->getX() + personaje->getAncho() - MARGEN_X, personaje->getY() + personaje->getAlto() );
	Punto infIzq (personaje->getX() + MARGEN_X, personaje->getY() + personaje->getAlto());
	Punto supDer (personaje->getX() + personaje->getAncho() - MARGEN_X, personaje->getY());
	Punto supIzq (personaje->getX(), personaje->getY());

/*
        cout << "ColisionOblicua ";
        cout << " infDerX " << infDer.getX() << " infDerY " << infDer.getY();
        cout << " infIzqX " << infIzq.getX() << " infIzqY " << infIzq.getY();
        cout << " supDerX " << supDer.getX() << " supDerY " << supDer.getY();
        cout << " supIzqX " << supIzq.getX() << " supIzqY " << supIzq.getY();
        cout << endl;
*/
        
//      if(getAngulo() > 90){ cout<<"angulo >90!!!!!!!!!!!!!!!!!!!"<<endl;
//      cout<<"************Entro a col oblicua!*****:  "<<per->getY()<<endl;
//      cout<<"plat y= "<<getY()<<"  plat x= "<<getX()<<endl;
//      cout<<"alto = "<<getAlto()<<"  ancho="<<getAncho()<<endl;
//      cout<<infIzq.getX()<<","<<infIzq.getY()<<")  es inf izq y alto="<<per->getAlto()<<endl;
//      cout<<"Posicion inf dere x="<<vertices.posInfDer.getX()<< "y = "<< vertices.posInfDer.getY()<<endl;
//      cout<<"Posicion inf Izq x="<<vertices.posInfIzq.getX()<< "y = "<< vertices.posInfIzq.getY()<<endl;
//      cout<<"Posicion Sup dere x="<<vertices.posSupDer.getX()<< "y = "<< vertices.posSupDer.getY()<<endl;
//      cout<<"Posicion Sup Izq x="<<vertices.posSupIzq.getX()<< "y = "<< vertices.posSupIzq.getY()<<endl;
//      cout<<"personaje: x="<<per->getX()<<"  y="<<per->getY()<<"  ancho="<<per->getAncho()<<endl;
//      }

	//int xInfMed = per->getX() + per->getAncho() / 2 ;

	if (DetectarInclusion(infIzq.getX(), infIzq.getY())) {
		double m = (vertices.posSupIzq.getY() - vertices.posSupDer.getY());
		double m1 = vertices.posSupIzq.getX() - vertices.posSupDer.getX();
		m = m / m1;

		double b = vertices.posSupIzq.getY() - m * vertices.posSupIzq.getX();
		int yFixed = m * (per->getX()) + b;
		personaje->setPosicion(personaje->getX(), yFixed - per->getAlto());
		per->setVelocidadY(0);
		if (per->getEstado() == EstadoBasico::Saltando)
			per->setEstado(EstadoBasico::Quieto);
		//cout << "entre inf izq" << endl;

		return true;
	} else if (DetectarInclusion(infDer.getX(), infDer.getY())) {
		//double distancia = per->getX() - per->getPosicionAnt().getX();
		double m = (vertices.posSupIzq.getY() - vertices.posSupDer.getY());
		double m1 = vertices.posSupIzq.getX() - vertices.posSupDer.getX();
		m = m / m1;

		double b = vertices.posSupIzq.getY() - m * vertices.posSupIzq.getX();
		int yFixed = m * (per->getX() + per->getAncho()) + b;
		personaje->setPosicion(personaje->getX(), yFixed - per->getAlto());
		per->setVelocidadY(0);
		if (per->getEstado() == EstadoBasico::Saltando)
			per->setEstado(EstadoBasico::Movimiento);
		//cout << "entre inf der" << endl;

		return true;
	} 
        /*

        else if(per->getVelocidadY() < 0 ){

		double m = (vertices.posInfIzq.getY() - vertices.posInfDer.getY());
		double m1 = vertices.posInfIzq.getX() - vertices.posInfDer.getX();
		m = m / m1;
		double b = vertices.posInfIzq.getY() - m * vertices.posInfIzq.getX();
		double yRecInf = m * (per->getX() + (per->getAncho() / 2)) + b;

		m = (vertices.posSupIzq.getY() - vertices.posSupDer.getY());
		m1 = vertices.posSupIzq.getX() - vertices.posSupDer.getX();
		m = m / m1;
		b= vertices.posSupIzq.getY() - m * vertices.posSupIzq.getX();
		double yRecSup = m * (per->getX() + (per->getAncho() / 2)) + b;

//              cout<<"yRec="<<yRecInf<<endl;
		if ((per->getY()+per->getAlto()) < yRecInf && (per->getY()+per->getAlto()) > yRecSup){
				cout<<"entro con y="<<per->getY()<<endl;
				per->setPosicion(per->getX(), yRecInf);
				per->setVelocidadY( - per->getVelocidadY());
		}
	}
  */
	else if(per->getVelocidadY() > 0 ){
		double m = (vertices.posInfIzq.getY() - vertices.posInfDer.getY());
		double m1 = vertices.posInfIzq.getX() - vertices.posInfDer.getX();
		m = m / m1;
		double b = vertices.posInfIzq.getY() - m * vertices.posInfIzq.getX();
		double yRecInf = m * (per->getX() + (per->getAncho() / 2)) + b;

		m = (vertices.posSupIzq.getY() - vertices.posSupDer.getY());
		m1 = vertices.posSupIzq.getX() - vertices.posSupDer.getX();
		m = m / m1;
		b= vertices.posSupIzq.getY() - m * vertices.posSupIzq.getX();
		double yRecSup = m * (per->getX() + (per->getAncho() / 2)) + b;

//		cout<<"yRec="<<yRecInf<<endl;
		if (per->getY() < yRecInf && per->getY() > yRecSup){
			//cout<<"entro con y="<<per->getY()<<endl;
			per->setPosicion(per->getX(), yRecInf);
			per->setVelocidadY( - per->getVelocidadY());
		}
//		cout<<"salio con y="<<per->getY()<<endl;
	}else if (DetectarInclusion(supDer.getX(), supDer.getY())) {
	double aux1,aux2;	
	double m, b;
	aux1 = (vertices.posSupIzq.getY() - vertices.posInfIzq.getY());
	aux2 = (vertices.posSupIzq.getX() - vertices.posInfIzq.getX());
	m = aux1/ aux2; 
	//cout<<"m"<<m<<endl;
	b = vertices.posSupIzq.getY() - m * vertices.posSupIzq.getX();
	double xIzq = (supDer.getY()-b)/m;
	if(per->getPosicionAnt().getX()<xIzq) per->setPosicion(xIzq- per->getAncho(),per->getY());
		//double distancia = per->getX() - per->getPosicionAnt().getX();
		
		return true;
	} 
	else if ((DetectarDobleInclusion(per, vertices.posSupIzq.getX(), vertices.posSupIzq.getY()) ||
			DetectarDobleInclusion(per, vertices.posSupDer.getX(), vertices.posSupDer.getY()))
			&&(per->getEstado()!=EstadoBasico::Movimiento)) {

			personaje->setPosicion(per->getPosicionAnt().getX(), per->getPosicionAnt().getY());
			per->setEstado(EstadoBasico::Quieto);
			per->setVelocidadY(0);
//			cout<<" verti sup izq y der"<<endl;
			return true;
	} else if(DetectarDobleInclusion(per, vertices.posInfIzq.getX(), vertices.posInfIzq.getY())){
		personaje->setPosicion(per->getX(), vertices.posInfIzq.getY());
		//per->setEstado(EstadoBasico::Quieto);
		per->setVelocidadY(- per->getVelocidadY());
//		cout<<"vertice inf izq "<<endl;
		return true;

	}else if(DetectarDobleInclusion(per, vertices.posInfDer.getX(), vertices.posInfDer.getY())){

		personaje->setPosicion(per->getX(), vertices.posInfDer.getY());
		//per->setEstado(EstadoBasico::Quieto);
		per->setVelocidadY(- per->getVelocidadY());
//		cout<<"vertice inf der "<<endl;
		return true;


	}
	else if (per->getEstado()!= EstadoBasico::Saltando){

		//cout<<"bla bla"<<endl;

		double m = (vertices.posSupIzq.getY() - vertices.posSupDer.getY()) ;
		double m1=vertices.posSupIzq.getX() - vertices.posSupDer.getX();
		m= m/m1;
		double b= vertices.posSupIzq.getY() - m* vertices.posSupIzq.getX();
		int yIzq = m * (per->getX())+ b;
		int yDer = m *(per->getX()+per->getAncho()) + b;
		if(per->getY()<yIzq || per->getY()< yDer){
			if(yIzq>yDer){
				per->setPosicion(per->getX(),yDer-per->getAlto());
			}else{
				per->setPosicion(per->getX(),yIzq-per->getAlto());
			}

		}
	}
//	else cout<<"no entro a nada"<<endl;

		
	return false;
}

